package zoran.wang.proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import zoran.wang.utils.LogUtils;

import java.lang.reflect.Method;

/**
 * description：
 *
 * @author wangzhuo
 * @date 2022/3/19 20:09
 * @Email zoranwang@yeah.net
 */
public class CglibProxyFactory {

    public static Object createCglibProxy(Object target) {
        //1. 增强器，负责产生一个Cglib代理对象实例
        Enhancer enhancer = new Enhancer();

        //2. 指定目标对象
        enhancer.setSuperclass(target.getClass());

        //3. 设置方法拦截器
        enhancer.setCallback(new MethodInterceptor() {
            /**
             * 只要代理对象方法调用，就会执行intercept方法
             * @param proxy 代理对象实例
             * @param method 调用方法的反射对象
             * @param args 调用方法时传递的参数
             * @param methodProxy 方法反射对象的代理对象
             * @return
             * @throws Throwable
             */
            @Override
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //前置增强
                LogUtils.logBefore(method.getName(), args);

                Object result = null;

                try {
                    //通过反射调用方法
                    result = method.invoke(target, args);
                    LogUtils.logAfterReturning(method.getName(), result);

                } catch (Exception e) {
                    LogUtils.logAfterThrowing(method.getName(), e);
                    throw new RuntimeException(e);

                }

                return result;
            }
        });

        //返回Cglib代理对象的实例
        return enhancer.create();
    }

}
